'''
    逐笔数据按天模拟推送
'''

import sys

from module.common import Config
from module.common.common import secs2str,summerTime
import time
import json
import traceback
import pika
from module.data.MysqlHelper import MysqlHelper
from module.data.PreTickerHandler import stockInfo,getTickerRecords,preTickerHandler

from module.const.Constant import const
from module.utils import TaskAdminUtil

import logging
log = logging.getLogger("handlelog")

class PushTickerSimulater(object):
    def __init__(self, queque, taskid):
        credentials = pika.PlainCredentials(Config.rabbitmq_user, Config.rabbitmq_passwd)
        self.connection = pika.BlockingConnection(pika.ConnectionParameters(
            host=Config.rabbitmq_host, port=Config.rabbitmq_port, credentials=credentials))
        self.channel = self.connection.channel()

        # 消息队列
        self.queuename = queque
        # 策略任务id
        self.taskid = taskid

    def ticker_data_push(self, curtask, ticker_data):
        # 声明消息队列，消息将在这个队列传递，如不存在，则创建
        self.channel.queue_declare(queue=self.queuename)  # 先以股票代码作为通道名称

        # 数据格式梳理
        code = curtask[0]
        data_date = curtask[1]
        open_price = ticker_data[0][1]

        uscnTimeDif = 46800
        sd, ed = summerTime(data_date)
        if sd < data_date < ed:
            uscnTimeDif = 43200
        sinfo = stockInfo(code, data_date, curtask[2])
        prev_close_price = sinfo[0] if sinfo[0] else open_price
        high_price = sinfo[1] if sinfo[1] else open_price
        low_price = sinfo[2] if sinfo[2] else open_price
        volume = sinfo[3] + ticker_data[0][2]
        turnover = sinfo[4] + ticker_data[0][1]*ticker_data[0][2]

        # 延迟推送，当前数据的下一条数据，和当前数据的时间差就是延时的时间
        index = 0
        dataLen = len(ticker_data)
        while index < dataLen-1:
            try:
                taskCenter = TaskAdminUtil.pullTaskCenter(self.taskid)
                # 任务手动暂停判断
                if taskCenter[1] == const.TASK_STATUS_STOP:
                    if curtask[4] == const.TASK_STATUS_STOP or not (code == taskCenter[0]['code'][0]):
                        log.info("%s任务 PushTickerSimulater触发手动暂停 详情信息：%s" % (self.taskid, curtask))
                        break
                # 任务异常判断
                if taskCenter[1] == const.TASK_STATUS_EXCEPT:
                    if curtask[4] == const.TASK_STATUS_EXCEPT or not (code == taskCenter[0]['code'][0]):
                        log.info("%s任务 PushTickerSimulater触发异常暂停 详情信息：%s" % (self.taskid, curtask))
                        break

                curticker = list(ticker_data[index])
                data_time = secs2str(curticker[0])[11:]
                if high_price < curticker[1]:
                    high_price = curticker[1]
                if low_price > curticker[1]:
                    low_price = curticker[1]
                volume += curticker[2]
                turnover += curticker[1] * curticker[2]
                change = round(curticker[1] - prev_close_price, 3)
                change_rate = round(change / prev_close_price*100, 2)
                dt = secs2str(curticker[0] + uscnTimeDif)
                simulat_quote = {
                    'code': code,
                    'data_date': data_date,
                    'data_time': data_time,
                    'prev_close_price': prev_close_price,
                    'last_price': curticker[1],
                    'open_price': open_price,
                    'high_price': high_price,
                    'low_price': low_price,
                    'volume': volume,
                    'turnover': turnover,
                    'change': change,
                    'change_rate': change_rate,
                    'market_val': 0,
                    'dt': dt
                }

                self.push_handler(curtask, simulat_quote, curticker, ticker_data[index + 1])
            except TypeError as err:
                log.error("type error msg: %s, data: %s" % (err, curticker))
                traceback.print_exc()
            except KeyError as err:
                log.error("key error msg: %s, data: %s" % (err, curticker))
                traceback.print_exc()
            except SyntaxError as err:
                log.error("syntax error msg: %s, data: %s" % (err, curticker))
                traceback.print_exc()
            finally:
                index += 1

    def push_handler(self, task, quoteItem, curdata, nextdata):
        stockname = task[0]
        # [time, price, volume]
        message = json.dumps({'taskid': self.taskid, 'stock_name': task[5], 'task': task, 'item': quoteItem})
        self.channel.basic_publish(exchange='', routing_key=self.queuename, body=message)
        if curdata[0] >= nextdata[0]:
            pass
        else:
            log.info("PushTickerSimulater推送前后两笔逐笔： %s %s" % (curdata, nextdata))
            sleepTime = nextdata[0] - curdata[0]
            time.sleep(sleepTime)


    def shutdown(self):
        # 队列清空暂停
        self.connection.close()

print('测试')
if __name__ == '__main__':
    simulater = PushTickerSimulater("US.AAPL33", "")
    task = ['US.AAPL', '2021-08-23', '09:30:00', '09:30:08',0]

    #datademo = MysqlHelper()
    #startdatetime = "%s %s" % (task[1], task[2])
    #enddatetime = "%s %s" % (task[1], task[3])
    #tickerData = datademo.loadTickerData(task[0], startdatetime, enddatetime)

    tickerData = preTickerHandler(task[0], task[1], task[2], task[3])
    simulater.ticker_data_push(task, tickerData)